/*
 *
 *   Copyright (C) 2005 by Raymond Huang
 *   plushuang at users.sourceforge.net
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *  ---
 *
 *  In addition, as a special exception, the copyright holders give
 *  permission to link the code of portions of this program with the
 *  OpenSSL library under certain conditions as described in each
 *  individual source file, and distribute linked combinations
 *  including the two.
 *  You must obey the GNU Lesser General Public License in all respects
 *  for all of the code used other than OpenSSL.  If you modify
 *  file(s) with this exception, you may extend this exception to your
 *  version of the file(s), but you are not obligated to do so.  If you
 *  do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source
 *  files in the program, then also delete it here.
 *
 */

#include <string.h>
#include <urlglib/url_info.h>
#include "download_info_view.h"
#include "proxy_list_view.h"
#include "urlgfe_util.h"
#include <urlglib/ug_i18n.h>

static void on_dialog_response (GtkDialog *dlg, gint response, DownloadInfoView* view)
{
	gchar* path;

	if (response == GTK_RESPONSE_ACCEPT ) {
		path = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dlg));
		path = g_filename_to_utf8 (path, -1, NULL, NULL, NULL);
		gtk_entry_set_text (GTK_ENTRY(view->entry_dir), path);
		g_free (path);
	}
	gtk_widget_destroy (GTK_WIDGET(dlg));
}

//	signal handler
static void on_choose_directory(GtkWidget* button, DownloadInfoView* view)
{
	GtkWidget* chooser;
	gchar* path;

	chooser = gtk_file_chooser_dialog_new ("Select Directory",
	                                       view->parent,
	                                       GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
	                                       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
	                                       GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
	                                       NULL);
	gtk_window_set_transient_for (GTK_WINDOW (chooser), view->parent);
	gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser), TRUE);

	path = (gchar*)gtk_entry_get_text (GTK_ENTRY (view->entry_dir));
	if (*path) {
		path = g_filename_from_utf8 (path, -1, NULL, NULL, NULL);
		gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), path);
		g_free (path);
	}

	g_signal_connect (chooser, "response", G_CALLBACK (on_dialog_response), view);
	gtk_widget_show (chooser);
}

static void on_login_toggled (GtkWidget* button, DownloadInfoView* view)
{
	gboolean sensitive;

	sensitive = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(view->toggle_login));

	gtk_widget_set_sensitive (view->label_username, sensitive);
	gtk_widget_set_sensitive (view->label_password, sensitive);
	gtk_widget_set_sensitive (view->entry_username, sensitive);
	gtk_widget_set_sensitive (view->entry_password, sensitive);
}

static void on_filename_changed (GtkEditable* eable, DownloadInfoView* view)
{
	if (view->url_changed == FALSE)
		view->auto_complete = FALSE;
}

//	DownloadInfoView method --------------------------------------
void download_info_view_url_changed (DownloadInfoView* view)
{
	UrlInfo*  uinfo;
	gchar*    filename;

	view->url_changed = TRUE;    // set status during URL changed

	if ( view->auto_complete ) {
		uinfo = url_info_new (gtk_entry_get_text (GTK_ENTRY(view->entry_url)));
		if (uinfo->filename_len) {
			filename = url_info_get_filename (uinfo);
			gtk_entry_set_text (GTK_ENTRY(view->entry_filename), filename);
			g_free (filename);
		} else {
			gtk_entry_set_text (GTK_ENTRY(view->entry_filename), "index.htm");
		}
		url_info_free (uinfo);
	}

	view->url_changed = FALSE;    // clear status
}

void download_info_view_init (DownloadInfoView* view)
{
	GtkWidget* top_table;
	GtkWidget* label;
	GtkWidget* table;
	GtkWidget* frame;
	GtkWidget* vbox;
	GtkWidget* hbox;
	GtkEditable* editable;

	// initialize
	view->auto_complete = TRUE;
	view->url_changed   = FALSE;
	view->multiple      = FALSE;
	view->parent = NULL;
	view->self = gtk_notebook_new ();
	top_table  = gtk_table_new (6, 3, FALSE);
	label = gtk_label_new (_("Download option"));
	gtk_container_set_border_width (GTK_CONTAINER (top_table), 2);
	gtk_notebook_append_page (GTK_NOTEBOOK (view->self), top_table, label);

	// URL Label & Entry
	view->entry_url = gtk_entry_new ();
	gtk_entry_set_width_chars (GTK_ENTRY (view->entry_url), 24);
	view->label_url = gtk_label_new_with_mnemonic (_("_URL:"));
	gtk_label_set_mnemonic_widget (GTK_LABEL(view->label_url), view->entry_url);
	gtk_table_attach (GTK_TABLE (top_table), view->label_url,
	                  0, 1, 0, 1, GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (top_table), view->entry_url,
	                  1, 3, 0, 1, GTK_FILL, GTK_SHRINK, 1, 2);

	// "Referer" label & entry
	view->entry_referer = gtk_entry_new ();
	view->label_referer = gtk_label_new_with_mnemonic (_("_Referer:"));
	gtk_label_set_mnemonic_widget (GTK_LABEL(view->label_referer),
	                               view->entry_referer);
	gtk_table_attach (GTK_TABLE (top_table), view->label_referer,
	                  0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (top_table), view->entry_referer,
	                  1, 3, 1, 2, GTK_FILL, GTK_SHRINK, 1, 2);

	// "Save to" label , entry & folder button
	view->button_folder = gtk_button_new ();
	gtk_container_add (GTK_CONTAINER (view->button_folder),
	    gtk_image_new_from_stock (GTK_STOCK_OPEN, GTK_ICON_SIZE_SMALL_TOOLBAR));
//	gtk_button_set_relief (GTK_BUTTON (view->button_folder), GTK_RELIEF_NONE);
	view->combo_dir = gtk_combo_box_entry_new_text ();
	view->entry_dir = GTK_WIDGET (GTK_BIN (view->combo_dir)->child);
	label = gtk_label_new_with_mnemonic (_("S_ave to:"));
	gtk_label_set_mnemonic_widget(GTK_LABEL(label), view->combo_dir);
	download_info_view_set_history (view, directory_history_get ());
	gtk_table_attach (GTK_TABLE (top_table), label,
	                  0, 1, 2, 3, GTK_SHRINK, GTK_SHRINK, 3, 1);
	gtk_table_attach (GTK_TABLE (top_table), view->combo_dir,
	                  1, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_SHRINK, 1, 1);
	gtk_table_attach (GTK_TABLE (top_table), view->button_folder,
	                  2, 3, 2, 3, GTK_SHRINK, GTK_SHRINK, 1, 1);

	// "rename" label & entry
	view->entry_filename = gtk_entry_new ();
	view->label_filename = gtk_label_new_with_mnemonic (_("Re_name:"));
	gtk_label_set_mnemonic_widget (GTK_LABEL(view->label_filename),
	                               view->entry_filename);
	gtk_table_attach (GTK_TABLE (top_table), view->label_filename,
	                  0, 1, 3, 4, GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (top_table), view->entry_filename,
	                  1, 2, 3, 4, GTK_FILL, GTK_SHRINK, 1, 2);

	// HBox for "Start mode" and "Login"
	hbox = gtk_hbox_new (FALSE, 2);
	gtk_table_attach (GTK_TABLE (top_table), hbox, 0, 3, 4, 5,
	                  GTK_FILL | GTK_EXPAND, GTK_SHRINK, 2, 2);

	// frame for start mode
	frame = gtk_frame_new (_("Start mode"));
	gtk_box_pack_start (GTK_BOX (hbox), frame, FALSE, FALSE, 0);
	vbox = gtk_vbox_new (FALSE, 2);
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
	gtk_container_add (GTK_CONTAINER(frame), vbox);
	view->radio_auto = gtk_radio_button_new_with_mnemonic (NULL,
	                                                       _("Au_tomatic"));
	view->radio_manual = gtk_radio_button_new_with_mnemonic_from_widget (
	                             (GtkRadioButton*)view->radio_auto,
	                             _("_Manual"));
	gtk_box_pack_start (GTK_BOX (vbox), view->radio_auto, FALSE, FALSE, 0);
	gtk_box_pack_start (GTK_BOX (vbox), view->radio_manual, FALSE, FALSE, 0);

	// frame for login
	frame = gtk_frame_new (_("Login"));
	gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 4);
	table = gtk_table_new (3, 2, FALSE);
	gtk_container_set_border_width (GTK_CONTAINER (table), 2);
	gtk_container_add (GTK_CONTAINER(frame), table);
	view->toggle_login = gtk_check_button_new_with_mnemonic (_("_Login to Server"));
	gtk_table_attach (GTK_TABLE (table), view->toggle_login,
	                  0, 2, 0, 1, GTK_FILL, GTK_SHRINK, 3, 2);
	view->entry_username = gtk_entry_new ();
	view->label_username = gtk_label_new_with_mnemonic (_("Username:"));
	gtk_label_set_mnemonic_widget (GTK_LABEL(view->label_username), view->entry_username);
	gtk_table_attach (GTK_TABLE (table), view->label_username,
	                  0, 1, 1, 2, GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (table), view->entry_username,
	                  1, 2, 1, 2, GTK_FILL, GTK_SHRINK, 1, 2);
	view->entry_password = gtk_entry_new ();
	view->label_password = gtk_label_new_with_mnemonic (_("Password:"));
	gtk_entry_set_visibility (GTK_ENTRY (view->entry_password), FALSE);
	gtk_label_set_mnemonic_widget (GTK_LABEL(view->label_password), view->entry_password);
	gtk_table_attach (GTK_TABLE (table), view->label_password,
	                  0, 1, 2, 3, GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (table), view->entry_password,
	                  1, 2, 2, 3, GTK_FILL, GTK_SHRINK, 1, 2);

	// frame for other option
	frame = gtk_frame_new (_("Other option"));
	gtk_table_attach (GTK_TABLE (top_table), frame, 0, 3, 5, 6,
	                  GTK_FILL | GTK_EXPAND, GTK_SHRINK, 2, 2);
	table = gtk_table_new (3, 2, FALSE);
	gtk_container_add (GTK_CONTAINER(frame), table);
	gtk_container_set_border_width (GTK_CONTAINER (table), 2);

	view->spin_retry = gtk_spin_button_new_with_range (0.0, 99.0, 1.0);
	label = gtk_label_new_with_mnemonic (_("Retry ma_x:"));
	gtk_label_set_mnemonic_widget (GTK_LABEL(label), view->spin_retry);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
	                  GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (table), view->spin_retry, 1, 2, 0, 1,
	                  GTK_SHRINK, GTK_SHRINK, 3, 2);

	view->spin_delay = gtk_spin_button_new_with_range (0.0, 600.0, 1.0);
	label = gtk_label_new_with_mnemonic (_("R_etry delay:"));
	gtk_label_set_mnemonic_widget (GTK_LABEL(label), view->spin_delay);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
	                  GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (table), view->spin_delay, 1, 2, 1, 2,
	                  GTK_SHRINK, GTK_SHRINK, 3, 2);

	view->spin_redirect = gtk_spin_button_new_with_range (0.0, 30.0, 1.0);
	label = gtk_label_new_with_mnemonic (_("Re_direction max:"));
	gtk_label_set_mnemonic_widget (GTK_LABEL(label), view->spin_redirect);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
	                  GTK_SHRINK, GTK_SHRINK, 3, 2);
	gtk_table_attach (GTK_TABLE (table), view->spin_redirect, 1, 2, 2, 3,
	                  GTK_SHRINK, GTK_SHRINK, 3, 2);

	// Download Page signal ------------------------------------------
	editable = GTK_EDITABLE (view->entry_url);
	g_signal_connect_swapped (editable, "changed",
	                          G_CALLBACK(download_info_view_url_changed), view);
	editable = GTK_EDITABLE (view->entry_filename);
	g_signal_connect (editable, "changed", G_CALLBACK(on_filename_changed), view);

	g_signal_connect (view->toggle_login, "toggled", G_CALLBACK(on_login_toggled), view);
	g_signal_connect (view->button_folder, "clicked", G_CALLBACK(on_choose_directory), view);


	// notebook page - "Proxy" ---------------------------------------

	// attach proxy setting view
	// add page
	label = gtk_label_new (_("Proxy"));
	proxy_editor_init (&view->proxy_editor);
	gtk_notebook_append_page (GTK_NOTEBOOK (view->self), view->proxy_editor.top_widget, label);
	on_login_toggled (view->toggle_login, view);

	gtk_widget_show_all (view->self);

	// set default page and focus
	gtk_notebook_set_current_page (GTK_NOTEBOOK (view->self), 0);
	gtk_widget_grab_focus (view->entry_url);
}

void download_info_view_apply (DownloadInfoView* view, DownloadNode* dnode)
{
	gtk_entry_set_text (GTK_ENTRY (view->entry_dir),
	                    (dnode->directory) ? dnode->directory: "");
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(view->spin_redirect),
	                           dnode->redirect_max);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(view->spin_retry),
	                           dnode->retry_max);
	gtk_spin_button_set_value (GTK_SPIN_BUTTON(view->spin_delay),
	                           dnode->retry_delay);
	gtk_entry_set_text (GTK_ENTRY(view->entry_referer),
	                    (dnode->referer) ? dnode->referer: "");
	gtk_entry_set_text (GTK_ENTRY(view->entry_username),
	                    (dnode->username) ? dnode->username: "");
	gtk_entry_set_text (GTK_ENTRY(view->entry_password),
	                    (dnode->password) ? dnode->password: "");
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (view->toggle_login),
	                              dnode->login);

	switch (dnode->start_mode) {
	case DOWNLOAD_START_AUTO:
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(view->radio_auto), TRUE);
		break;
	case DOWNLOAD_START_MANUAL:
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(view->radio_manual), TRUE);
		break;
	}

	proxy_editor_set (&view->proxy_editor, dnode);
}

void download_info_view_set (DownloadInfoView* view, DownloadNode* dnode)
{
	download_info_view_apply (view, dnode);

	gtk_entry_set_text (GTK_ENTRY(view->entry_url),
	                    (dnode->url) ? dnode->url : "");
	gtk_entry_set_text (GTK_ENTRY(view->entry_filename),
	                    (dnode->filename) ? dnode->filename : "");
	if (dnode->filename==NULL)
		download_info_view_url_changed (view);
}

void download_info_view_get (DownloadInfoView* view, DownloadNode* dnode)
{
	if( dnode==NULL )
		return;
//	proxy_setting_view_get (&view->proxy_info_view,
//	                        &dnode->proxy);

	download_node_set_directory (dnode, gtk_entry_get_text (GTK_ENTRY(view->entry_dir)) );

	dnode->redirect_max = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(view->spin_redirect));
	dnode->retry_max = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(view->spin_retry));
	dnode->retry_delay = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(view->spin_delay));

	download_node_set_referer (dnode, gtk_entry_get_text (GTK_ENTRY(view->entry_referer)) );

	dnode->login = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (view->toggle_login));
	download_node_set_username (dnode, gtk_entry_get_text (GTK_ENTRY(view->entry_username)) );
	download_node_set_password (dnode, gtk_entry_get_text (GTK_ENTRY(view->entry_password)) );

	if ( view->multiple==FALSE ) {
		download_node_set_filename (dnode,
				gtk_entry_get_text (GTK_ENTRY(view->entry_filename)) );
		download_node_set_url (dnode,
				gtk_entry_get_text (GTK_ENTRY(view->entry_url)) );
	}

	if ( gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(view->radio_auto)) )
		download_node_set_start_mode (dnode, DOWNLOAD_START_AUTO);
	else
		download_node_set_start_mode (dnode, DOWNLOAD_START_MANUAL);

	proxy_editor_get (&view->proxy_editor, dnode);
}

void download_info_view_set_url (DownloadInfoView* view, const gchar* url)
{
	view->auto_complete = TRUE;
	gtk_entry_set_text (GTK_ENTRY(view->entry_url), (url) ? url : "");
}

gint download_info_view_check_field (DownloadInfoView* view)
{
	UrlInfo*  uinfo;
	const gchar *dir, *fname, *url;
	gboolean valid_url;

	dir   = gtk_entry_get_text (GTK_ENTRY(view->entry_dir));
	fname = gtk_entry_get_text (GTK_ENTRY(view->entry_filename));
	url   = gtk_entry_get_text (GTK_ENTRY(view->entry_url));

	// complete filename from URL & check URL.
	uinfo = url_info_new (url);
	valid_url = (uinfo->address) ? TRUE : FALSE;
	url_info_free (uinfo);

	if (view->multiple)
		return (*dir) ? DOWNLOAD_INFO_COMPLETE : DOWNLOAD_INFO_UNCOMPLETE;

	if ( *dir==0 || *fname==0 || *url==0 )
		return DOWNLOAD_INFO_UNCOMPLETE_MULTIPlE;

	return (valid_url) ? DOWNLOAD_INFO_COMPLETE : DOWNLOAD_INFO_UNCOMPLETE_URL;
}

void download_info_view_set_history (DownloadInfoView* dsv, GList* directory_history)
{
	GList* node;
	GtkComboBox* combo = GTK_COMBO_BOX (dsv->combo_dir);

	for (node=directory_history; node; node=node->next)
		gtk_combo_box_append_text (combo, node->data);
}

void download_info_view_set_multiple (DownloadInfoView *view, gboolean multiple)
{
	gboolean sensitive;

	view->multiple = multiple;

	if ( multiple ) {
		gtk_widget_hide (view->entry_url);
		gtk_widget_hide (view->entry_filename);
		gtk_widget_hide (view->label_url);
		gtk_widget_hide (view->label_filename);
		sensitive = FALSE;
	}
	else {
		gtk_widget_show (view->entry_url);
		gtk_widget_show (view->entry_filename);
		gtk_widget_show (view->label_url);
		gtk_widget_show (view->label_filename);
		sensitive = TRUE;
	}
	gtk_widget_set_sensitive (view->entry_url, sensitive);
	gtk_widget_set_sensitive (view->entry_filename, sensitive);
	gtk_widget_set_sensitive (view->label_url, sensitive);
	gtk_widget_set_sensitive (view->label_filename, sensitive);

//	gtk_widget_set_sensitive (view->toggle_login, sensitive);
//	gtk_widget_set_sensitive (view->label_id, sensitive);
//	gtk_widget_set_sensitive (view->entry_id, sensitive);
//	gtk_widget_set_sensitive (view->label_password, sensitive);
//	gtk_widget_set_sensitive (view->entry_password, sensitive);
}

